neutron.setTitle("Terminal")
neutron.setMinSize(420, 340)
neutron.getInfo((data) => {
    if (data[0]["w"] < 420) {
        neutron.setWinSize(600, 400)
    }
});

// 工具函数
function base64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');

    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);

    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}
function bytesToBase64(bytes) {
    const binString = Array.from(bytes, (byte) =>
        String.fromCodePoint(byte),
    ).join("");
    return btoa(binString);
}


// 宽高
var last_w = 0
var last_h = 0
var term = null
var websocket = null

window.onload = function () {
    neutron.loadData((data) => {

        // 从session还原termid
        var termid = 0;
        if (data[0] == null) {
            termid = 0;
        } else {
            termid = data[0]["termid"]
        }

        // 初始化终端
        term = new Terminal({
            rows: 1,
            cols: 1,
            convertEol: true,
            scrollback: 1000,
            disableStdin: false,
            cursorBlink: false,
            cursorStyle: "underline",
            theme: { // 白色主题，互换黑白
                foreground: "#3b3b3b",
                selectionBackground: "#ADD5FF",
                selectionInactiveBackground: "#E5EBF1",
                background: "#FFFFFF",
                white: "#3b3b3b",
                brightWhite: "#000000",
                black: "#FFFFFF",
                brightBlack: "#E0E0E0",
                cursor: "#3b3b3b",
                cursorAccent: "#5b5b5b",
                lineHeight: 14,
            },
            fontFamily: "Editor Fonts",
        });
        // 自动跳转大小插件
        const fitAddon = new FitAddon.FitAddon();
        term.loadAddon(fitAddon);

        // 缩放
        window.addEventListener("resize", resizeScreen)
        function resizeScreen() {
            try {
                fitAddon.fit()
            } catch (e) {
                console.log("Error:", e.message)
            }
        }

        // 设置xtermjs
        term.open(document.getElementById('container'));
        function load_bash() {
            fitAddon.fit()
            // 欢迎提示
            term.write('Welcome to use \x1B[1;34mneutron panel\x1B[0m!\n\n')
            websocket = new WebSocket(API_PATH + "/ws?termid=" + termid);
            neutron.onClose(() => { // 关闭窗口
                try {
                    websocket.send(JSON.stringify({
                        "type": "close",
                    }));
                } catch (e) {

                }
                neutron.close()
            })
            // 发送数据
            term.onData(key => {
                if (websocket.readyState == 1) {
                    websocket.send(JSON.stringify({
                        "type": "data",
                        "data": bytesToBase64(new TextEncoder().encode(key))
                    }))
                }
            })
            // 接受数据
            websocket.onmessage = function (event) {
                json = JSON.parse(event.data)
                if (json["type"] == "data") {
                    term.write(base64ToUint8Array(json["data"]))
                }
            };
            // 自动设置缩放
            var intervobj = setInterval(() => {
                if (websocket.readyState == 1) {
                    websocket.send(JSON.stringify({
                        "type": "resize",
                        "data": [term.rows, term.cols]
                    }))
                } else {
                    clearInterval(intervobj)
                }
            }, 1000)

            websocket.onopen = function () {
                if (window.location.search.length == 0) {
                    return
                }
                var params = new URLSearchParams(window.location.search);

                websocket.send(JSON.stringify({
                    "type": "data",
                    "data": bytesToBase64(new TextEncoder().encode(params.get('cmd') + "\n"))
                }))
            }

        }
        setTimeout(() => {
            // 获取最新termid
            if (termid == 0) {
                var xhr = new XMLHttpRequest();
                xhr.open("GET", API_PATH + "/new", true);
                xhr.onreadystatechange = function () {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var json = JSON.parse(xhr.responseText);
                        termid = json["termid"]
                        neutron.saveData({
                            "termid": termid
                        })
                        load_bash()
                    }
                }
                xhr.send()
            } else {
                load_bash()
            }

        }, 60)
    })
}

function contains(list, value) {
    for (var i = 0; i < list.length; ++i) {
        if (list[i] === value) return true;
    }
    return false;
}

function text_dragover(e) {
    if (!contains(e.dataTransfer.types, "application/neutron-file-transfer") && !contains(e.dataTransfer.types, "text/plain") && !contains(e.dataTransfer.types, "text/uri-list")) {
        return
    }
    e.preventDefault()
    e.stopPropagation()
}

function text_rewrite(text) {
    var add_space = text.includes(" ")
    if (text.includes("@") || text.includes("$") || text.includes("#")) {
        add_space = true
    }
    text = text.replace(/\$/g, "\\$")
    if (add_space) {
        text = '"' + text + '"'
    }
    return text
}

function text_drop(e) { // 文件拖拽
    if (contains(e.dataTransfer.types, "application/neutron-file-transfer")) { // neutron 文件管理器
        var datas = JSON.parse(e.dataTransfer.getData("application/neutron-file-transfer"))
        from_tmp = datas["from"]
        if (from_tmp == "/") {
            from_tmp = ""
        }
        if (websocket.readyState == 1) {
            websocket.send(JSON.stringify({
                "type": "data",
                "data": bytesToBase64(new TextEncoder().encode(datas["filelist"].map(index => text_rewrite(from_tmp + "/" + index["name"])).join(" ")))
            }))
        }
        e.preventDefault()
        e.stopPropagation()
    } else if (contains(e.dataTransfer.types, "text/plain")) { // 纯文本
        if (websocket.readyState == 1) {
            websocket.send(JSON.stringify({
                "type": "data",
                "data": bytesToBase64(new TextEncoder().encode(text_rewrite(e.dataTransfer.getData("text/plain"))))
            }))
        }
        e.preventDefault()
        e.stopPropagation()
    } else if (contains(e.dataTransfer.types, "text/uri-list")) { // URL
        if (websocket.readyState == 1) {
            websocket.send(JSON.stringify({
                "type": "data",
                "data": bytesToBase64(new TextEncoder().encode(text_rewrite(e.dataTransfer.getData("text/uri-list"))))
            }))
        }
        e.preventDefault()
        e.stopPropagation()
    }
}

